﻿using System;
using DataProcessModule.Protocol;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;
using System.Data;
/* 报文处理类 ，根据协议命令字解析数据，将数据解析完后上传数据库 */
namespace DataProcessModule
{
    public class BytProcess
    {
        //public static System.Threading.ReaderWriterLockSlim WrtLock = new System.Threading.ReaderWriterLockSlim();
        public object BytArLock;
        public List<byte[]> BytArr;
        public Dictionary<string, UInt32> FireboxVersionInfos;
        private System.Timers.Timer UpgradeInfoDraw = new System.Timers.Timer();
        private string SqlConnStr;
        public BytProcess(byte[] _byts){
            _initializor();
            //ConfigrationSettingsReader.ReadConfig();
            ByteDigitsForge(_byts);
           
        }
        public BytProcess() 
        {
            _initializor();
        }
        public void _initializor()
        {
            FireboxVersionInfos = new Dictionary<string, uint>();
            SqlConnStr = ConfigrationSettingsReader.SqlConnectAddress;
            BytArr = new List<byte[]>();
            BytArLock = new object();

            UpgradeInfoCompareGet();
            UpgradeInfoGet();
            UpgradeInfoDraw.Interval = ConfigrationSettingsReader.AtUpgradeSendFreq;
            UpgradeInfoDraw.Elapsed += new System.Timers.ElapsedEventHandler(UpgradeInfoDraw_Elapsed);
            UpgradeInfoDraw.Start();            
        }
        private void UpgradeInfoDraw_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            System.Threading.ThreadPool.QueueUserWorkItem(t =>
            {
                UpgradeInfoCompareGet();
                UpgradeInfoGet();
            });
        }

        private void UpgradeInfoCompareGet()
        {
            System.Data.DataTable _dt = Class_mysql_conn.Get_DataTable("select UploadSequence,TerminalKey,SoftwareVersion from table_firebox_version_upload_"
                + DateTime.Now.ToString("yyyyMMdd") + ';', SqlConnStr, "table_firebox_version_upload_" + DateTime.Now.ToString("yyyyMMdd"));
            if (_dt.Rows.Count == 0 || _dt == null) return;
            foreach (DataRow DtRow in _dt.Rows) 
            {
                FireboxVersionInfos[DtRow["TerminalKey"].ToString()] = StrToInt(DtRow["SoftwareVersion"].ToString());
            }
        }

        private void UpgradeInfoGet()
        {
            System.Data.DataTable _dt = Class_mysql_conn.Get_DataTable("select * from table_fire_box_software_upgrade;", SqlConnStr, "table_fire_box_software_upgrade");
            if (_dt.Rows.Count == 0 || _dt == null) return;
            foreach (DataRow DtRow in _dt.Rows)
            {
                FireboxSoftwareUpgrade _fsu = new FireboxSoftwareUpgrade();
                try
                {
                    if (DtRow[0].ToString().Length < 8 
                        || DtRow["Upgradable"].ToString() == "0"
                        || FireboxVersionInfos[DtRow["TerminalKey"].ToString()] == StrToInt(DtRow["UpgradeVersion"].ToString())) continue;
                    _fsu.TerminalKey = DtRow["TerminalKey"].ToString();
                    _fsu.AtUpgradeVersion = DtRow["UpgradeVersion"].ToString();
                    _fsu.AtUpgradeFireboxID = DtRow["UpgradeFireboxID"].ToString();
                    _fsu.AtFTPServerAddress = DtRow["FTPServerAddress"].ToString();
                    _fsu.AtFilePath = DtRow["FilePath"].ToString();
                    _fsu.AtFileName = DtRow["FileName"].ToString();
                    _fsu.AtMD5CheckCode = DtRow["MD5CheckCode"].ToString();
                    lock (BytArLock)
                    {
                        BytArr.Add(_fsu.GenerateInstructionStream());
                    }
                    Class_mysql_conn.Run_SQL("UPDATE table_fire_box_software_upgrade SET Upgradable=0 WHERE TerminalKey='" + _fsu.TerminalKey + "';", SqlConnStr);
                }
                catch (Exception e)
                {                
                    return;
                }
               
            }
        }
        public string GetDeviceTerminalkey(byte[] _byts)
        {
            try 
            {
                int offset = 0;
                byte[] destinationArray = new byte[_byts.Length - 2];
                Array.Copy(_byts, 1, destinationArray, 0, _byts.Length - 2);

                byte[] buffer = Utilities.UnConvertFlag(destinationArray, 0, destinationArray.Length);
                InstHead instructionHead = BaseInstruction.GetInstructionHead(buffer, ref offset);
                string _sqlcmd  = FireboxSoftwareUpgrade.AutoUpgradeString(instructionHead.tdPhoneNumber);
                if (_sqlcmd != string.Empty)
                {
                    int _res = Class_mysql_conn.Run_SQL(_sqlcmd, SqlConnStr);
                    _sqlcmd = string.Empty;
                }
                return instructionHead.tdPhoneNumber;
            }
            catch (Exception e) { return e.Message; }            
        }
        public void ByteDigitsForge(byte[] _byts)
        {
            string _sqlcmd = string.Empty;
            //string sqlconnectaddress = ConfigrationSettingsReader.SqlConnectAddress;
            try
            {
               
                int offset = 0;
                byte[] destinationArray = new byte[_byts.Length - 2];
                Array.Copy(_byts, 1, destinationArray, 0, _byts.Length - 2);

                byte[] buffer = Utilities.UnConvertFlag(destinationArray, 0, destinationArray.Length);             
                InstHead instructionHead = BaseInstruction.GetInstructionHead(buffer, ref offset);          
                switch (instructionHead.instID)
                {
                    case 0x0111:
                        {
                            FireboxStatsReport FireboxStatsReportIns = new FireboxStatsReport(buffer);
                            _sqlcmd = FireboxStatsReportIns.InsertString();
                            goto Lable_UpLoad;
                        }
                    case 0x0112:
                        {
                            CarCurrentStats CarCurrentStatsIns = new CarCurrentStats(buffer);
                            _sqlcmd = CarCurrentStatsIns.InsertString();
                            goto Lable_UpLoad;
                        }
                    case 0x0113:
                        {
                            SingleBatteryVoltageStats SingleBatteryVoltageStatsIns = new SingleBatteryVoltageStats(buffer);
                            _sqlcmd = SingleBatteryVoltageStatsIns.InsertString();
                            goto Lable_UpLoad;
                        }
                    case 0x0114:
                        {
                            MotorBatteryPackTempratureStats MotorBatteryPackTempratureStatsIns = new MotorBatteryPackTempratureStats(buffer);
                            _sqlcmd = MotorBatteryPackTempratureStatsIns.InsertString();
                            goto Lable_UpLoad;
                        }
                    case 0x0115:
                        {
                            MotorBatteryAlarmStats MotorBatteryAlarmStatsIns = new MotorBatteryAlarmStats(buffer);
                            _sqlcmd = MotorBatteryAlarmStatsIns.InsertString();
                            goto Lable_UpLoad;
                        }
                    case 0x0116:
                        {
                            FireboxSoftwareUpgrade FireboxSoftwareUpgradeIns = new FireboxSoftwareUpgrade(buffer);
                            _sqlcmd = FireboxSoftwareUpgradeIns.CombinedSqlString();
                            goto Lable_UpLoad;
                        }
                    case 0x0117:
                        {
                            SoftwareVersionReport SoftwareVersionReportIns = new SoftwareVersionReport(buffer);
                            _sqlcmd = SoftwareVersionReportIns.InsertString();
                            goto Lable_UpLoad;
                        }
                    case 0x0118:
                        {
                            TimeRequest TimeRequestIns = new TimeRequest(buffer);
                            ServerActionsHandle(ServerAction.TimeReport,TimeRequestIns.TerminalKey);
                            _sqlcmd = TimeRequestIns.CombinedSqlString();
                            goto Lable_UpLoad;
                        }
                    case 0x9116:
                        {
                            UpgradeFeedback UpgradeFeedbackIns = new UpgradeFeedback(buffer);
                            _sqlcmd = UpgradeFeedbackIns.CombinedSqlString();
                            goto Lable_UpLoad;
                        }
                    default:
                        {
                            //break;
                            goto Lable_UpLoad;
                        }
                }
                Lable_UpLoad:
                if (_sqlcmd != string.Empty)
                {
                    int _res =Class_mysql_conn.Run_SQL(_sqlcmd, SqlConnStr);
                    _sqlcmd = string.Empty;
                }
                //System.Threading.ThreadPool.QueueUserWorkItem(t => Class_mysql_conn.Run_SQL(_sqlcmd,ConfigrationSettingsReader.SqlConnectAddress));
                
            }
            catch (Exception e) { }

        }
        public void ServerActionsHandle(ServerAction sa,string tknum) 
        {
            BaseInstruction instruction = null;       
            try 
            {
                switch (sa)
                {
                    case ServerAction.UpgradeFirebox:
                        {
                            FireboxSoftwareUpgrade _fsu = new FireboxSoftwareUpgrade();
                            _fsu.TerminalKey = tknum;
                            instruction = _fsu;
                            goto Label_SendCommand;
                        }
                    case ServerAction.TimeReport:
                        {
                            TimeReply _tr = new TimeReply();
                            instruction = _tr;
                            _tr.TerminalKey = tknum;
                            goto Label_SendCommand;
                        }
                    default:
                        {
                            goto Label_SendCommand;
                        }
                }
                Label_SendCommand:
                if (instruction != null)
                {
                    lock (BytArLock)
                    {
                        BytArr.Add(instruction.GenerateInstructionStream());
                    }
                }
            }
            catch (Exception e) { }     
        }
        public UInt32 StrToInt(string str)
        { 
            //Int64 num = 0;
            if (str.Length % 2 != 0) return 0;
            byte[] _byt = System.Helpers.BC.FromBCDString(str,0,str.Length);
            UInt32 num = System.Helpers.BC.ToUInt32Net(_byt,0);
            return num;
        }
    }
}



